package org.forgerock.openicf.connectors.rsaauthenticationmanager;
import org.identityconnectors.common.security.GuardedString;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import org.identityconnectors.common.logging.Log;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* Utility class for the RSA Connector
*
* @author Alex Babeanu (ababeanu@nulli.com)
* www.nulli.com - Identity Solution Architects
*
* @version 1.1
* @since 1.0
*/
public class RSAAuthenticationManager8Utils {
/**
* Encryption/decryption password for the encryption utility below.
* <br/>
* This could be improved depending on the requirements of the implementation.
* For example, the password could be passed as a system property. At the very least
* this hard-coded password should be changed from an implementation to another.
*/
private static final char[] PASSWORD = "enfldsabllx3gdlpsdqgm".toCharArray();
/**
* Salt for the encryption algorithm
*/
private static final byte[] SALT = {
(byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12,
(byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12,
};
/**
* logger
*/
private static final Log logger = Log.getLog(RSAAuthenticationManager8Utils.class);
public RSAAuthenticationManager8Utils() {
super();
}
/**
* Returns the plain password of a GuardedString
*
* @param password the GuardedString storing the encrypted pwd to decrypt and return.
* @return A String representing the clear text password.
*/
public static String getPlainPassword(GuardedString password) {
if (password == null) {
return null;
}
final StringBuffer buf = new StringBuffer();
password.access(new GuardedString.Accessor() {
public void access(char[] clearChars) {
buf.append(clearChars);
}
});
return buf.toString();
}
/**
* Encrypts the given string - assumed to be a config property- using the
* constant pwd and salt using MD5 and DES.
*
* @param property the String to encrypt
* @return an encrypted representation of the string.
*
* @throws GeneralSecurityException
* @throws UnsupportedEncodingException
*/
public static String encrypt(String property) throws GeneralSecurityException, UnsupportedEncodingException {
// DEBUG:
//logger.info("Encrypting property: {0}.", property);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
return base64Encode(pbeCipher.doFinal(property.getBytes("UTF-8")));
}
private static String base64Encode(byte[] bytes) {
// DEBUG:
//logger.info("Base 64 encoding bytes: {0}.", bytes.toString());
return new BASE64Encoder().encode(bytes);
}
public static String decrypt(String property) throws GeneralSecurityException, IOException {
// DEBUG:
//logger.info("Decrypting property: {0}--.", property);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
return new String(pbeCipher.doFinal(base64Decode(property)), "UTF-8");
}
private static byte[] base64Decode(String property) throws IOException {
// DEBUG:
//logger.info("Base 64 decoding property: {0}.", property);
return new BASE64Decoder().decodeBuffer(property);
}
}